# encoding=utf-8

import code, time, six, websocket, json, threading
from instruction import ins_login, ins_register, ins_newguide,ins_talk_switch

OPCODE_DATA = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)

## 自动注册登录机器人!!! 
## 只需要传入 用户名和密码!!!
class Bot(threading.Thread):
    def __init__(self, uname, pwd):
        super(Bot, self).__init__(name=uname)
        self.ws = None
        
        self.prepare = None
        self.task = None

        self.username = uname
        self.password = pwd

    def set_register_addr(self, addr):
        self.regsiter_addr = addr
    
    def set_login_addr(self, addr):
        self.login_addr = addr

    def set_prepare(self, prepare):
        self.prepare = prepare

    # set main_task
    def set_task(self, task, interval, times = -1):
        self.task = task
        self.interval = interval
        self.times = times

    def run(self):
        # 1. Exec register to server if need
        if self.register():
            # 1.1 新账号注册成功，切换登录
            if self.login():
                # 1.2 发送新手指引 (注册为百姓号)
                self.complish_newguide()
            else:
                self.log('注册+登录都失败，账号名密码错误；该账号不可用...或者该改BUG了！！！！')
                return
        else:
            # 注册失败，尝试登录
            self.log('注册失败, 尝试登录...')
            state = self.login()
            if state == 'LOGIN_NEWGUIDE':
                self.complish_newguide()
            elif state == True:
                self.log('登录成功，该账号已经完成注册')
            else:
                self.log('登录失败，退出进程')
                return

        ##
        ## 完成登录动作后，执行任务
        ##

        # 2. Exec prepare task
        if self.prepare != None:
            self.prepare(self)
            
        # 3. Exec main task
        if self.times >= 0:
            while self.times > 0:
                time.sleep(self.interval)
                self.task(self)
                self.times -= 1    
        else:
            while True:
                time.sleep(self.interval)
                self.task(self)

    ##============================================================
    ## 登录/注册 接口
    ##============================================================

    def login(self): 
        self.ws = websocket.create_connection(self.login_addr)
        self._send(ins_login(self.username, self.password)[0])
        rr = self.recv_data()
        resp = json.loads(rr)
        if resp['id'] == '100017':
            self.log('登录成功: %s', self.recv_data())
            self.talk_switch()
            return True
        elif resp['id'] == '100052':
            self.log('需要进入开场剧情...')
            self.talk_switch()
            return 'LOGIN_NEWGUIDE'
        else:
            print rr
            self.log('登录失败，%s', resp['errmsg'].encode('utf-8'))
            return False

    def login_check(self):
        # 检查当前登录后的，状态
        pass

    def register(self):
        self.ws = websocket.create_connection(self.regsiter_addr)
        self._send(ins_register(self.username, self.password)[0])
        resp = json.loads(self.recv_data())
        
        if resp['res'] == 0:
            self.log('注册失败: %s', resp['errmsg'].encode('utf-8'))
            return False
        elif resp['res'] == 1:
            self.log('注册成功，密码：%s', self.password)
            return True
        return False
    
    def complish_newguide(self):
        # 完成新手任务
        for c in ins_newguide():
            self.send_ins([c])
            time.sleep(0.5)

    def talk_switch(self):
        self.send_ins(ins_talk_switch())
    ##============================================================
    ## Logger
    ##============================================================

    def log(self, msg, *args):

        print ('[%s]%s' + msg) % ((self.username, ' ') + args)

    ##============================================================
    ## 底层 WS 收发接口
    ##============================================================

    def send_ins(self, Ins):
        for m in Ins:
            self._send(m)
            self.recv_data()

    def send(self, Msg):
        return self._send(Msg)

    def recv_data(self):
        opcode, data = self._recv()
        print '[%s] RECV: %.100s' % (self.username, data)

        return data

    def _send(self, Msg):
        print '[%s] SEND: %.100s' % (self.username, Msg)
        return self.ws.send(Msg)

    def _recv(self):
        try:
            frame = self.ws.recv_frame()
        except websocket.WebSocketException:
            return websocket.ABNF.OPCODE_CLOSE, None
        if not frame:
            raise websocket.WebSocketException("Not a valid frame %s" % frame)
        elif frame.opcode in OPCODE_DATA:
            return frame.opcode, frame.data
        elif frame.opcode == websocket.ABNF.OPCODE_CLOSE:
            ws.send_close()
            return frame.opcode, None
        elif frame.opcode == websocket.ABNF.OPCODE_PING:
            ws.pong(frame.data)
            return frame.opcode, frame.data

        return frame.opcode, frame.data
